<template>
  <FGDialog ref="FGDialog" title="请选择" width="900px" top="8vh" @confirm="onConfirm">
    <el-row :gutter="0" class="Fg-user-picker">
      <el-col :span="12" class="Fg-user-picker-left">
        <el-input
          v-if="type != 'dept'"
          v-model="searchValue"
          :placeholder="search.text"
          size="small"
          @keyup.enter.native="handleSearch"
        ></el-input>
        <FGBreadNav icon="el-icon-office-building" :nav.sync="breadNav" @onNav="onNav" />
        <div style="margin-left:10px">
          <el-checkbox v-model="checkedAll" @change="toggleAll" :disabled="!multiple">全选</el-checkbox>
          <span v-if="breadNav.length" class="blue preNext" @click="onPre">上一级</span>
        </div>
        <div class="Fg-user-picker-list">
          <div
            v-for="(item) in list"
            :key="item[defaultProps.id]"
            @click.stop.prevent="handleChange([item], !item.selected,item.disabled)"
            class="Fg-user-picker-item Fg-user-picker-hover"
          >
            <el-checkbox v-model="item.selected" :disabled="item.disabled"></el-checkbox>
            <div class="Fg-user-picker-user">
              <div class="avatar">
                <el-avatar :size="34" :src="item[defaultProps.avatar]"></el-avatar>
              </div>
              <span>{{item[defaultProps.name]}}</span>
              <template v-if="item[defaultProps.type] == 'dept'">
                <div class="blue next" @click.stop.prevent="handleNext(item)">下级</div>
              </template>
            </div>
          </div>
        </div>
      </el-col>
      <el-col :span="12" class="Fg-user-picker-right">
        <div class="Fg-user-picker-right--top">
          <span>已选 {{checkList.length}} 项</span>
          <el-button type="text" style="color: #c75450;" @click="handleClear">清空</el-button>
        </div>
        <div class="Fg-user-picker-list">
          <div
            class="Fg-user-picker-user Fg-user-picker-hover"
            v-for="(item,index) in checkList"
            :key="item[defaultProps.id]"
          >
            <div class="avatar">
              <el-avatar :size="34" :src="item[defaultProps.avatar]"></el-avatar>
            </div>
            <span>{{item[defaultProps.name]}}</span>
            <el-icon class="next" @click.stop.prevent="handleCancel(item,index)"><Close /></el-icon>
            <!-- <i class="el-icon-close next" @click.stop.prevent="handleCancel(item,index)"></i> -->
          </div>
        </div>
      </el-col>
    </el-row>
  </FGDialog>
</template>

<script>
import { requestUrl } from "@/api/data";
import defaultUser from "@/images/defaultUser.png";
import defaultUnit from "@/images/defaultUnit.png";
import { unionFun, differenceSetFun } from "@/components/formGenerator/utils";
import { deepClone } from "../../../utils/index";
import FGBreadNav from "../../../huComponents/FGBreadNav";
import { ElMessageBox } from "element-plus";

export default {
  name: "UserPicker",
  components: {
    FGBreadNav,
  },
  props: {
    type: {
      default: "user", // org选择部门/人员  user-选人  dept-选部门 role-选角色
      type: String,
    },
    multiple: {
      // 是否多选
      default: false,
      type: Boolean,
    },
    data: {
      type: Object,
      default: () => {},
    },
    // 搜索配置
    search: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      searchValue: "",
      state: false,
      list: [], // 已选中用户
      checkList: [],
      loading: false,
      checkedAll: false,
      breadNav: [], // 存储显示到面包屑导航中的数据
    };
  },
  computed: {
    requestProps() {
      return this.data.props.request || {};
    },
    responseProps() {
      return this.data.props.response || {};
    },
    defaultProps() {
      return {
        name: "name",
        id: "id",
        type: "type",
        portraitURL: this.responseProps.avatar,
        ...this.responseProps,
      };
    },
  },

  methods: {
    init() {
      this.checkList = [];
      this.breadNav = [];
      this.list = [];
      this.checkedAll = false;
      this.searchValue = "";
      this.list = []; // 已选中用户
    },
    open(checkList) {
      this.init();
      // 回显已选中数据
      if (checkList) {
        this.checkList = checkList.map((item) => {
          let obj = item;
          obj[this.defaultProps.avatar] = {
            dept: defaultUnit,
            user: defaultUser,
          }[item[this.defaultProps.type]];
          return obj;
        });
      }
      this.loadData();
      this.$refs.FGDialog.open();
    },

    toggleAll(value) {
      this.checkedAll = value;
      const list = this.list.filter((item) => !item.disabled);
      this.handleChange(list, value);
    },
    // 清空
    handleClear() {
      ElMessageBox.confirm("您确定要清空已选中的项?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        this.checkList = [];
        this.filterCheckList();
      });
    },
    // 删除某项
    handleCancel(item, index) {
      this.checkList.splice(index, 1);
      this.filterCheckList();
    },
    // 下级
    handleNext(item) {
      // 将当前组织架构名存储在面包屑导航中
      this.breadNav.push({
        text: item[this.defaultProps.name],
        id: item[this.defaultProps.id],
      });
      this.breadNav = [...new Set(this.breadNav)];
      this.loadData(item[this.defaultProps.id]);
    },

    // 点击面包屑导航
    onNav(index, id) {
      this.loadData(id);
    },
    onPre() {
      this.breadNav.pop();
      const id = this.breadNav[this.breadNav.length - 1]?.id || "";
      this.loadData(id);
    },

    // 单独点击某个多选框/全选框
    // list-发生改变的单位数组，state-需要改变的状态 true-选中，false-取消选中
    handleChange(list, state, disabled) {
      if (disabled) return;
      if (!this.multiple) this.checkList = [];
      if (state) {
        // 并集即为选中
        this.checkList = unionFun(this.checkList, list, this.defaultProps.id);
      } else {
        // 差集即为取消选中
        this.checkList = differenceSetFun(
          this.checkList,
          list,
          this.defaultProps.id
        );
      }
      this.filterCheckList();
    },

    // 过滤当前选中
    filterCheckList() {
      // 在这里更新数据
      const checkedIds = this.checkList.map(
        (item) => item[this.defaultProps.id]
      );
      this.list.forEach((item) => {
        item.selected = false;
        if (checkedIds.includes(item[this.defaultProps.id]))
          item.selected = true;
      });
      // 判断当前列表中的数据是否有被全选
      // if (this.list.every((item) => item.selected)) {
      //   this.checkedAll = true;
      // } else {
      //   this.checkedAll = false;
      // }
      this.$forceUpdate();
    },

    // 确认分享
    onConfirm() {
      const checkList = deepClone(this.checkList);
      checkList.forEach((item) => {
        delete item.selected;
      });
      this.$emit("callBack", checkList);
      this.$emit("update:modelValue", checkList);
      this.$refs.FGDialog.close();
    },
    // 搜索
    handleSearch() {
      if (!this.searchValue) return this.loadData();
      let data = this.search.request;
      data[this.search.props.request.userName] = this.searchValue;
      this.list = [];
      this.loading = true;
      requestUrl(
        this.search.url,
        this.search.method,
        data,
        this.search.reDataType
      )
        .then((rsp) => {
          let arr = [];
          if (rsp.result.userList.length) {
            const user = rsp.result.userList.map(val => {
              return  {
                  "id": val.userID,
                  "name": val.name,
                  "portraitURL": null,
                  "type": "user"
                }
            })
            const org = rsp.result.orgList.map(val => {
              return  {
                  "id": val.orgID,
                  "name": val.orgName,
                  "portraitURL": null,
                  "type": "dept"
                }
            })
            arr = arr.concat(user).concat(org);
          }
          this.list = (arr.length ? arr :rsp.result).map((item) => {
            let obj = {
              ...item,
              disabled:
                item[this.defaultProps.type] !== "user" && this.type == "user",
            };
            obj[this.defaultProps.avatar] = {
              dept: defaultUnit,
              user: defaultUser,
            }[item[this.defaultProps.type]];
            return obj;
          });

          this.filterCheckList();
          if (this.search?.response) {
            const func = new Function("response", this.search.response);
            func(rsp.result);
          }
        })
        .catch((err) => {
          if (this.search?.error) {
            const func = new Function("error", this.search.error);
            func(err);
          }
        })
        .finally(() => {
          this.loading = false;
          this.finished = true;
        });
    },

    loadData(deptId) {
      let data = deepClone(this.data.request);
      this.list = [];
      if (deptId) data = Object.assign(data, { [this.requestProps.deptId]: deptId})
      this.loading = true;
      requestUrl(this.data.url, this.data.method, data, this.data.reDataType)
        .then((rsp) => {
          this.list = rsp.result.map((item) => {
            let obj = {
              ...item,
              disabled:
                item[this.defaultProps.type] !== "user" && this.type == "user",
            };
            obj[this.defaultProps.avatar] = {
              dept: defaultUnit,
              user: defaultUser,
            }[item[this.defaultProps.type]];
            return obj;
          });

          this.filterCheckList();
          if (this.data?.response) {
            const func = new Function("response", this.data.response);
            func(rsp.result);
          }
        })
        .catch((err) => {
          if (this.data?.error) {
            const func = new Function("error", this.data.error);
            func(err);
          }
        })
        .finally(() => {
          this.loading = false;
          this.finished = true;
        });
    },
  },
};
</script>

<style lang="scss" scoped>
$cell-height: 45px;
.Fg-user-picker {
  height: 60vh;
  overflow: auto;
  .preNext {
    cursor: pointer;
    margin-left: 20px;
  }
  .Fg-user-picker-list {
    overflow: auto;
    box-sizing: border-box;
  }
  .Fg-user-picker-left {
    border: 1px solid #e8e8e8;
    height: 100%;
    padding: 15px;
    .Fg-user-picker-list {
      height: calc(100% - 36px - 36px - 20px);
    }
  }
  .Fg-user-picker-right {
    border: 1px solid #e8e8e8;
    border-left: none;
    height: 100%;
    .Fg-user-picker-list {
      height: calc(100% - 50px);
      padding: 15px;
    }
    .Fg-user-picker-right--top {
      border-bottom: 1px solid #e8e8e8;
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 45px;
      padding: 0 15px;
    }
    .Fg-user-picker-user {
      padding: 0 50px;
      margin-bottom: 0;
      .avatar {
        left: 10px;
      }
      .next {
        right: 10px;
      }
    }
  }
  .Fg-user-picker-item {
    position: relative;
    padding-left: 35px;
    padding-right: 10px;
    height: $cell-height;
    line-height: $cell-height;
    display: flex;
    align-items: center;

    .el-checkbox {
      position: absolute;
      left: 10px;
    }
  }
}
.Fg-user-picker-hover {
  &:hover {
    cursor: pointer;
    background: #f1f1f1;
    border-radius: 5px;
    height: $cell-height;
  }
}
.Fg-user-picker-user {
  position: relative;
  padding: 0 40px;
  height: $cell-height;
  line-height: $cell-height;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 5px;

  .avatar {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    display: flex;
    align-items: center;
  }
  .next {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
  }
}
</style>
